package team.bluepen.supermarket.service.recommend.service;

import org.apache.commons.lang3.RandomUtils;
import team.bluepen.supermarket.data.entity.Product;
import team.bluepen.supermarket.service.recommend.core.ItemCF;
import team.bluepen.supermarket.service.recommend.core.UserCF;
import team.bluepen.supermarket.service.recommend.dto.ItemDTO;
import team.bluepen.supermarket.service.recommend.dto.RelateDTO;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 推荐服务
 *
 * @author YCB 2023/6/19 15:01
 */
public class Recommend {

    /**
     * 方法描述: UserCF
     *
     * @param userId 用户id
     * @Return {@link List<ItemDTO>}
     */
    public static List<ItemDTO> userCfRecommend(long userId, List<Product> products) {
        List<RelateDTO> data = FileDataSource.getData(products);
        List<Long> recommendations = UserCF.recommend(userId, data); //
        return FileDataSource.getItemData(products).stream()
                .filter(e -> recommendations.contains(e.getId()))
                .collect(Collectors.toList());
    }

    /**
     * 方法描述: ItemCF
     *
     * @param itemId 物品id
     * @Return {@link List<ItemDTO>}
     * @author tarzan
     * @date 2020年07月31日 17:28:06
     */
    public static List<ItemDTO> itemCfRecommend(long itemId, List<Product> products) {
        List<RelateDTO> data = FileDataSource.getData(products);
        List<Long> recommendations = ItemCF.recommend(itemId, data);
        List<ItemDTO> recommend = selectRecommend(itemId, products);
        List<ItemDTO> result = new ArrayList<>(recommend);


        List<ItemDTO> converted = FileDataSource.getItemData(products).stream()
                .filter(e -> recommendations.contains(e.getId()))
                .collect(Collectors.toList());
        result.addAll(subSize(converted, 7));
        return result;
    }

    private static List<ItemDTO> selectRecommend(long id, List<Product> products) {
        int[] recommendations = getRecommendations(id, products);
        List<Product> extract = extract(recommendations, products);
        return FileDataSource.getItemData(extract);
    }

    private static List<Product> extract(int[] indexes, List<Product> products) {
        List<Product> extract = new ArrayList<>();
        for (int index : indexes) {
            extract.add(products.get(index));
        }
        return extract;
    }

    private static int[] getRecommendations(long id, List<Product> products) {
        final int size = 3;

        int[] recommendations = new int[size];
        for (int i = 0; i < size; i++) {
            recommendations[i] = RandomUtils.nextInt(0, products.size());
        }
        return recommendations;
    }

    private static <T> List<T> subSize(List<T> list, int size) {
        if (list.size() <= size) {
            return list;
        }
        return list.subList(0, size);
    }
}
